package inseniarlingua.trans.en_ia;

import groovy.transform.CompileStatic;
import inseniarlingua.lang.en.AdjectiveEN;
import inseniarlingua.lang.en.NounEN;
import inseniarlingua.lang.en.VerbEngDef;
import inseniarlingua.lang.en.VerbsENFactory;
import inseniarlingua.lang.en.NounENFactory;
import inseniarlingua.lang.ia.AdjectiveIA;
import inseniarlingua.lang.ia.NounIA;
import inseniarlingua.lang.ia.VerbIA;
import inseniarlingua.lang.ia.NounIAFactory;
import inseniarlingua.lang.ia.VerbsIAFactory;
import inseniarlingua.lang.Noun;
import inseniarlingua.lang.Phrase;
import inseniarlingua.lang.TransPair
import inseniarlingua.lang.VerbDef;
import inseniarlingua.lang.WordDef;

//@CompileStatic
class Translator {
	private Map<String,String> transMap
	static Map<Phrase,Phrase> transRegExes
	static Map<VerbDef,VerbDef> transVerbMap
	static Map<Noun,Noun> transNounMap
	static private VerbsIAFactory verbIAFactory = new VerbsIAFactory()
	static private VerbsENFactory verbENFactory = new VerbsENFactory()
	static NounIAFactory nounIAFactory = new NounIAFactory()
	static NounENFactory nounENFactory = new NounENFactory()
	
	static Map getTransNounMap()
	{
		if (transNounMap == null) {
			Map nounMap = [
				// A
				after: 'post',
			    animal: 'animal',
				article: 'articulo',
				
				// B
			    bed: 'lecto',
			    book: 'libro',
			    breakfast: 'jentaculo',
				breeze: 'brisa',
				
				// C
				cage: 'cavia', // CAGE [n] = cavia
				cat: 'catto',
				city: 'citate',
				chair: 'sedia',
				clock: 'horologio',
				coffer: 'coffro',
				coffie: 'caffe',
				color: 'color',
				comfychair: 'comfortabile',
				country: 'pais',
				
				// D
				day: 'die',
				dog: 'can',
				
				// F
				father: 'patre',
				family: 'familia',
				flower: 'flor',
				food: 'mangiar',
				friend: 'amico',
				gate: 'porta',
				garden: 'jardin',
				grandfather: 'granpatre',
				grandmother: 'granmatre',
				hora: 'hour',
				house: 'casa',
				idea: 'idea',
				invitation: 'invitation',
				
				// J
				jam: 'bloccar', // JAM n (conserve) confectura; (traffic) paralyse del circulation; (fix) difficultate; vt (squeeze in) serrar, comprimer; (obstruct) obstruer, bloccar; (of radio) bloccar con ruito; vi (get stuck) bloccar se
				journalist: 'journalista',
				
				// K
				key: 'clave',
				kitchen: 'cocina',
				land: 'pais',
				letter: 'littera',
				life: 'vita',
				livingroom: 'salon',
				'living room': 'salon',
				
				// M
				milk: 'lacte',
				magazine: 'magazin',
				man: 'homine',
				morning: 'matino',
				mother: 'matre',
				
				// N
				name: 'nomine',
				
				//P
				painting: 'pictura',
				party: 'partita',
				people: 'gente',
				post: 'posta',
				radio: 'radio',
				
				// R
				rest: 'resto', // REST n (repose) reposo; (remainder) resto; (support) appoio; (mus.) pausa; vt appoiar (un cosa super); vi reposar; AT - in reposo
				result: 'consequentia', // RESULT n resultato, consequentia; v resultar
				roof: 'tecto',
				room: 'camera',
				
				// S
				scar: 'cicatrice', // SCAR n cicatrice; vt marcar con un cicatrice; vi cicatrisar se
				sea: 'mar',
				snake: 'serpente',
				shirt: 'camisa',
				shoe: 'scarpa',
				shop: 'boteca',
				sock: 'calcea',
				sofa: 'sofa',
				sun: 'sol',
				sweater: 'sweater',
				
				// T
				table: 'tabula',
				tea: 'the',
				thing: 'cosa',
				toilet: 'w.c.',
				traffic: 'traffico', // TRAFFIC n (air, rail) movimentos; (road) circulation; (trade) commercio; (bad sense) traffico; v trafficar
				trouser: 'pantalone',
				
				// W
				week: 'septimana',
				wolf: 'lupo',
				woman: 'femina',
			]
			transNounMap = [:]
			nounMap.each {String en, String ia ->
				transNounMap.put(nounENFactory.getNoun(en), nounIAFactory.getNoun(ia));
			}
		}
		return transNounMap
	}
	
	static Map getTransVerbMap() 
	{
		if (transVerbMap == null) {
			Map verbMap = [
				// A
				attack: 'attaccar', //ATTACK n attacco; v attaccar
				answer: 'responder',
				ask: 'demandar',
				
				// B
				be: 'esser',
				become: 'devinir',
				begin: 'comenciar',
				
				// C
				can: 'poter',
				come: 'venir',
				'do': 'facer',
				drink: 'biber',
				
				// E
				escape: 'escappar', // ESCAPE n escappata; v escappar
				eat: 'mangiar',
				enjoy: 'gauder',
				
				// G
				get: 'obtener', // GET vt (receive) obtener, ganiar; (acquire) prender; (a disease) contraher, suffrer de; vi (become) devenir, facer se; (persuade) persuader; (reach) arrivar a; (make) facer; HAVE GOT TO deber
				give: 'dar',
				go: 'vader', // GO n (vim) vigor; (turn) tentativa, torno; v (move) ir, vader; (become) devenir; (depart) partir; (work) functionar
				
				// H
				have: 'haber',
				hope: 'sperar',
				
				// J
				jump: 'saltar', // JUMP n salto; v saltar
				lay: 'jacer',
				
				know: 'saper', // KNOW (facts) saper; (people and things) cognoscer; (recognize) recognocer
				// KNOW-HOW cognoscentia technic
				// KNOW-HOW-TO saper, saper como
				
				// L
				last: 'durar', // LAST adj ultime; adv in le ultime loco; n (for shoes) forma; v durar, permaner; AT - al fin; TO THE - usque al fin
				leap: 'saltar', //LEAP n salto; v saltar; anno bissextil
				leave: 'partir', // * LEAVE n permission; (absence) congedo; (mil.) commeato; vt lassar, quitar; vi partir
				/*
LEAVE-ALONE lassar in pace
LEAVE-BEHIND abandonar, relinquer
LEAVE-IN-THE-LURCH lassar in difficultate, in embarasso
LEAVE-OFF cessar
LEAVE-OUT omitter
				 */
				live: 'habitar',
				look: 'reguardar',
				love: 'amar',
				
				// M
				must: 'deber',
				open: 'aperir',
				
				/*
				 * OUT adj The English adjective "out" is usually a replacement of an adjective or adjective phrase.
				 * Thus to translate "out" as an adjective, one has to translate the adjective or phrase replaced, so that
				 * a fire is "extincte", a secret would be "cognoscite" and the tide "basse"; adv foras; as an English adverb,
				 * "out'' is often part of the verb, and is not therefore translated separately. Thus 'I go out" is "sortir",
				 * "hand out" distribuer" and the command "look out!? would translate as "attention!". Sometimes a verb might
				 * translate "out", so workmen taking industrial action "exopera" (= strike, are on strike); interj (sports) out!;
				 * MADE - OF fabricate de
OUT-AND-OUT complete
OUT-OF-BOUNDS foras de limites
OUT-OF-BOUNDS foras del limites
OUT-OF-BREATH sin halito
OUT-OF-DANGER foras de periculo
OUT-OF-DATE (lapsed) perimite; (old) antiquate, obsolete
OUT-OF-DATE (old) antiquate; (lapsed) perimite
OUT-OF-FASHION foras de moda
OUT-OF-KINDNESS per benevolentia
OUT-OF-MONEY curte de moneta
OUT-OF-ORDER (untidy) disordinate; (broken) in reparation
OUT-OF-PLACE (in the wrong place) displaciate; (inconvenient) inopportun
OUT-OF-PRINT exhaurite
OUT-OF-PROPORTION mal proportionate, disproportionate
OUT-OF-RESPECT per respecto
OUT-OF-SORTS indisposite
OUT-OF-STOCK exhaurite
OUT-OF-THE-HOUSE ex casa
OUT-OF-THE-ORDINARY exceptional, foras del commun
OUT-OF-THE-QUESTION impossibile
OUT-OF-THE-WAY (remote) remote; (over) terminate
OUT-OF-WORK disoccupate.
				 */
				'out of': 'foras de', // OUT-OF foras de; ex; (through) per
				
				// P
				play: 'jocar',
				put: 'poner',
				
				// R
				read: 'leger',
				receive: 'reciper',
				remove: 'remover',
				
				// S
				say: 'dicer',
				see: 'vider',
				send: 'inviar',
				show: 'monstrar',
				sing: 'cantar',
				sit: 'seder',
				sleep: 'dormir',
				smile: 'surrider',
				speak: 'parlar',
				spend: 'passar', //SPEND (money) dispender, expender; (time) passar
				struggle: 'luctar', // STRUGGLE n lucta; v luctar; (flail about, writhe) debatter se
				swim: 'natar',
				
				// T
				'take hold of': 'prender',
				talk: 'dicer',
				tell: 'dicer',
				tremble: 'tremular',
				
				// U
				use: 'usar',
				
				// V
				visit: 'visitar',
				
				// W
				wisper: 'susurrar',
				will: 'voler',
				
				// want
				want: 'voler',
//				walk: 'vader',
				walk: 'promenar',
				whisle: 'sibilar',
				worry: 'preoccupar', // preoccupar v I. to prejudice, bias; II. to preoccupy (1. to take possession of before others; 2. to take up all the attention of); preoccupar se de to be preoccupied with
				// WORRY n anxietate, inquietude; vt (worry) inquietar; (bother) vexar; vi inquietar se, perturbar se
				write: 'scriber',
			]
			transVerbMap = [:]
			verbMap.each { String en, String ia ->
				//println "$en $ia"
				transVerbMap.put(verbENFactory.getVerb(en), verbIAFactory.getVerb(ia));
			}
		}
		return transVerbMap;
	}
	
	static getTransRegExes() {
		if (transRegExes == null) {
			transRegExes = [:]
			transRegExes[new Phrase(["it", "is",  '*', "o'clock"])] = new Phrase(["es", null, '*',  "horas"])
			transRegExes[new Phrase(["today",  "it", "is", "*"])] = new Phrase(["hodie", null, 'es',  "*"])
			transRegExes[new Phrase(["remove",  "the", "*", "from"])] = new Phrase(["remove", "le", '*',  "ex"])
			//transRegExes[new Phrase([null, "*",  "days", "ago"])] = new Phrase(["ante", "*", "dies", null])
			//transRegExes[new Phrase(["do",  'you', "*"])] = new Phrase(['', "*", "tu"])
		}
		return transRegExes
	}
	
	@Newify([TransPair,AdjectiveEN,AdjectiveIA])
	public def getTransMap() {
		new AdjectiveEN('big')
		if (transMap == null) {
			transMap = [:]
			
			// nouns
			getTransNounMap().each { NounEN en, NounIA ia ->
				//println "en=$en, ia=$ia"
				transMap.put(en.singular, ia.singular)
				transMap.put(en.plural, ia.plural)
			} 
			
			// verbs
			getTransVerbMap().each { VerbEngDef en, VerbIA ia ->
				//println "en=$en, ia=$ia"
				transMap.put(en.infinitive, ia.infinitive)
				//transMap.put("to "+en.infinitive, ia.infinitive)
				transMap.put("is going to "+en.infinitive, "va a "+ia.infinitive) // alt ia.future 
				transMap.put("are going to "+en.infinitive, "va a "+ia.infinitive)
				transMap.put(en.present, ia.present)
				transMap.put(en.present2rdPerson, ia.present)
				transMap.put(en.present3rdPersonSingular, ia.present)
				transMap.put(en.past3rdPersonSingular, ia.past)
				transMap.put(en.past, ia.past)
				transMap.put("have "+en.perfect, ia.perfect)
				transMap.put("has "+en.perfect, ia.perfect)
			}
			//println "transMap=${transMap}"
			
			def map = [
				'!': '!',
				',': ',',
				the: 'le',
				of: 'de',
				and: 'e',
				to: 'a',
				in: 'in',
				I: 'io',
				that: 'que', // THAT adj ille; adv (so) si, tanto; conj que; pron illo; rel pron que, le qual; (who) qui, que, le qual(es)
				'that is': 'illo es',
				who: 'qui', // WHO pron (interrogative) qui; (relative) qui, le qual(es)
				//was: 'esseva',
				his: 'su',
				her: 'su',
				he: 'ille',
				she: 'illa',
				'it': 'illo', // IT (subject and after prep.) illo; (object) lo; (impersonal) il
				with: 'con',
				//is: 'es',
				for: 'pro',
				//had: 'habeva',
				as: 'como', // AS adv como; conj (since) pois que, proque; WHITE - SNOW si/tanto blanc como le nive
				you: 'tu',
				not: 'non',
				'to be': 'esser',
				on: 'sur',
				/*
				 *  at = 5091841 by = 5061050 which = 4580906 have = 4346500 or = 4228287 from = 4108111 this = 4015425 him = 3971997 but = 3894211 all = 3703342 she = 3415846 they = 3340398 were = 3323884 my = 3277699 are = 3224178 me = 3027134 one = 2832569 their = 2820265 so = 2802481 an = 2641417 said = 2637136 them = 2509917 we = 2491655 who = 2472663 would = 2400858 been = 2357654 will = 2320022 no = 2241145 when = 1980046 there = 1961200 if = 1951102 more = 1899787 out = 1875351 up = 1792712 into = 1703963 do = 1680164 any = 1665366 your = 1658553 what = 1605908 has = 1602329 man = 1573117 could = 1571110 other = 1533530 than = 1508779 our = 1498473 some = 1476767 very = 1462382 time = 1449681 upon = 1424595 about = 1414687 may = 1400642 its = 1373270 only = 1318367 now = 1317723 like = 1280625 little = 1273589 then = 1255636 can = 1210074 should = 1192154 made = 1188501 did = 1185720 us = 1171742 such = 1136757 a = 1135294 great = 1120163 before = 1117089 must = 1108116 two = 1093366 these = 1090510 see = 1084286 know = 1075612 over = 1056659 much = 1021822 down = 989808 after = 978575 first = 978196 mr = 974419 good = 966602 men = 923053
				 */
				a: 'un',
				//man: 'homine',
				//woman: 'femina', // TODO Need noun class
				'the woman': 'la femina',
				good: 'bon',
				here: 'ci',
				//are: 'es',
				Norway: 'Norvegia',
				they: 'illes',
				//live: 'habita',
				//have: 'ha',
				mister: 'senior',
				'mr.': 'sr.',
				misses: 'seniora',
				'mrs.': 'sra.',
				also: 'anque',
				brown: 'brun',
				black: 'nigre',
				small: 'parve',
				'small garden': 'jardin parve',
				//has: 'ha',
				//love: 'ama',
				//loves: 'ama',
				//sit: 'sede',
				//sits: 'sede',
				entire: 'tote',
				//read: 'lege',
				//reads: 'lege',
				interlingua: 'interlingua',
				international: 'international',
				'listen to': 'ascolta',
				//'listen to the': 'ascolta le',
				Scotland: 'Scotia',
				'sleeping room': 'camera a dormir',
				one: 'un',
				very: 'multo',
				'it is morning': 'il es matino',
				'woke up': 'se evelia',
				'looked at': 'reguarda',
				seven: 'septe',
				"o'clock": "horas",
				"can not": "non pote",
				sleep: "dormir",
				many: 'multe',
				because: 'proque',
				//like: 'ama',
				//likes: 'ama',
				'likes to read': 'ama leger',
				red: 'rubie',
				green: 'verde',
				black: 'nigre',
				blue: 'blau',
				yellow: 'jalne',
				//lay: 'jace',
				//lays: 'jace',
				'is not hearing': 'non audi',
				//open: 'aperi',
				//opens: 'aperi',
				'gets up from': 'se leva ab',
				//'walks': 'vade',
				into: 'a in',
				//sees: 'vide',
				//see: 'vide',
				'does not move': 'non se move',
				//wispers: 'susurra',
				//wisper: 'susurra',
				'do you sleep': 'dormi tu',
				'no':'no',
				'does not sleep': 'non dormi',
				//'jump': 'salta',
				//'jumps': 'salta',
				against: 'verso',
				'are you hungry': 'ha tu fame',
				//say: 'dice',
				//says: 'dice',
				miau: 'miau',
				yes: 'si',
				'is hungry': 'ha fame',
				//give: 'da',
				//gives: 'da',
				now: 'nunc',
				//come: 'veni',
				//comes: 'veni',
				'did you give': 'da tu',
				'are hungry': 'ha fame',
				'is hungry': 'ha fame',
				//drinks: 'bibe',
				//drink: 'bibe',
				'what do you want': 'que vole vos',
				'to drink': 'biber',
				//asks: 'demanda',
				//ask: 'demanda',
				//will: 'vole',
				pleasure: 'placer',
				//answer: 'responde',
				//answers: 'responde',
				'i would like': 'io vole con placer',
				'will you also drink': 'vole tu anque biber', // TODO biber should be in infinitiv
				whole: 'tote',
				'eat breakfast': 'jenta',
				what: 'que',
				'this': 'isto',

				// Numbers
				'two': 'duo',
				
				// Day related words
				yesterday: 'heri',
				today: 'hodie',
				tomorrow: 'deman',
				Monday: 'lunedi',
				Tuesday: 'martedi',
				Wednesday: 'mercuridi',
				Thursday: 'jovedi',
				Friday: 'venerdi',
				Saturday: 'sabbato',
				Sunday: 'dominica',
				
				there: 'il',
				'there is': 'il ha',
				'there are': 'il ha',
				from: 'ab',
				scottish: 'scotic',
				'scottish friend': 'amico scotic',
				'envelope': 'invelope',
				'opens the envelope in a hurry': 'hasta aperir le invelope',
				dear: 'car',
				'thanks a lot': 'multe gratias',
				"do not": 'non',
				//tell: 'narrar',
				//talk: 'narra',
				'tell you': 'dicer te',
				us: 'nos',
				//visited: 'visita',
				'visited us': 'nos visita',
				always: 'sempre',
				old: 'ancian',
				'old days': 'dies ancian',
				about: 'super', // ABOUT adv approximativemente, circa; prep (around) circa; (concerning) de, in re, super
				interesting: 'interessante',
				we: 'nos',
				them: 'les',
				//showed: 'monstrava',
				'showed them': 'les monstrava',
				//'it has': 'il ha',
				wheather: 'tempore',
				nice: 'bon',
				warm: 'calide',
				'it is warm': 'il es calide', 
				hot: 'calide',
				'is shining': 'brilla',
				ago: 'retro',
				met: 'encontrava',
				Dane: 'danese',
				'two days ago': 'ante duo dies',
				//spoke: 'parlava',
				evening: 'vespere',
				'the whole': 'tote le',
				use: 'usar',
				when: 'quando',
				"it is good that one": "es bon que on",
				soon: 'tosto',
				me: 'me',
				'will soon write': 'tosto scribe',
				new: 'nove',
				an: 'un',
				//'to the': 'al',
				'to the Miles family': 'al familia Myles',
				'can visit': 'potera visitar',
				'next': 'sequente',
				'next week': 'le septimana sequente',
				him: 'ille',
				themselves: 'se',
				'enjoyed themselves': 'se gaudeva',
				'enjoy themselves': 'se gaude',
				busy: 'occupate',
				//'is going to': 'va a',
				'take hold of': 'prender',
				afterwards: 'pois',
				'to put': 'poner',
				'in them': 'in illos',
				//'a narrar': 'to tell',
				all: 'omnes',
				glad: 'gaudiose',
				only: 'solmente',
				some: 'qualque',
				'a journalist': 'journalista',
				or: 'o',
				am: 'es',
				rich: 'ric',
				talent: 'talento',
				modern: 'moderne',
				'modern painting': 'pictura moderne',
				'what you': 'lo que tu',
				'must do': 'debe facer',
				at: 'a',
				home: 'a casa',
				'at home': 'a casa',
				but: 'ma',
				'look at': 'reguarda',
				discussion: 'discussion',
				'we had tea': 'biber the',
				often: 'frequentemente',
				hand: 'mano',
				foot: 'pede',
				pocket: 'tasca',
				like: 'como',
				pig: 'porco',
				battery: 'accumulator',
				smoke: 'fumo',
				detector: 'detector', // Not in any dict.
				'smoke detector': 'detector de fumo',
				spider: 'aranea',
				'bite': 'morsura',
				'spider bite': 'morsura de aranea',
				by: 'per',
				late: 'in retardo', // LATE adj (delayed) retardate, tardive; (recent) recente; (deceased) decedite; adv in retardo; BE - esser in retardo
				'traffic jam': 'paralyse de circulation', // TRAFFIC-JAM imbottiliamento/paralyse de circulation
				'as a result': 'como consequentia',
				able: 'capace', // ABLE capace, habile; BE - poter
				"I am not going to be": 'io non va a esser',
				"to do that": "facer illo",
				'to spend': 'passar',
				their: 'lor', // THEIR lor
				'their lives': 'lor vitas',
				together: 'conjunctemente', // TOGETHER conjunctemente, insimul
				//'a lot': 'multo', // LOT (fate) destino, sorte; (at auction) lot; (of land) parcella; A - multo; A - OF multe; DRAW -S
				'a lot of': 'multe',
				'to talk to': 'dicer a',
				'to get out of': 'pro partir',
				'if': 'si',
				'knows it': 'lo sape',
				'would not be': 'non esserea',
				//'be able to': 'capace de', // Does not work
				'able to tell': 'capace de dicer',
				'will last': 'vole durar',
				'my': 'mi', // MY mi
				'love you': 'te ama',
				'will love you': 'te amarea',
				'do you make of': 'tu pensa de',
				'to worry': 'preoccupar se',
				'any more': 'plus' // ANY-MORE plus (longe)
				/*
				 * ANY-FURTHER plus, plus longe
ANY-PLACE alicubi, ubique, in qulcunque loco
ANY-TIME aliquando
ANY-WAY de omne modo, de qualcunque maniera
ANY-WISE de qualcunque modo (maniera)
ANY (some) al(i)cun, al(i)cuno; (emphatic) qualcunque, ulle; IN - CASE in omne caso
ANYBODY al(i)cuno
ANYHOW (however) de omne modo, in omne caso, totevia; (in spite of everything) malgrado toto; (no matter how) de qualcunque maniera
ANYONE-ELSE un altere persona
ANYONE al(i)cuno
ANYTHING alique
ANYWHERE alicubi, ubique, usquam, in qualcunque modo
				 */
			]
			map.each { String k, v ->
				transMap[k] = v
			}
			
			for (TransPair tp in [new TransPair(new AdjectiveEN('big'), new AdjectiveIA('grande'))]) {
				transMap[((WordDef)tp.source).value.toString()] = ((WordDef)tp.target).value.toString()
			}
		}
		return transMap;
	}
	
	def translate(fromText) {
		Sentence sentence = new Sentence()
		sentence.transMap = getTransMap() 
		sentence.origSource = fromText
		sentence.translate()
		def ret = sentence.translation 
		println "${sentence.transPairs}"
		println "$fromText -> $ret"
		return ret
	}
}
